<template>
  <div class="file-list-container">
    <!-- 文件列表显示 -->
    <div class="file-list" :class="{ 'inline-wrap': inlineWrap }">
      <div
        v-for="(fileItem, index) in fileList"
        :key="typeof fileItem === 'string' ? index : fileItem.id || index"
        class="file-item"
        @click="handleFileClick(fileItem)"
      >
        <!-- 文件图标 -->
        <div class="file-icon" @click.stop="handlePreview(fileItem)">
          <img
            :src="getFileIcon(getFileUrl(fileItem))"
            :alt="getFileType(getFileUrl(fileItem))"
            class="file-type-icon"
          />
        </div>
        <!-- 文件信息 -->
        <div class="file-info">
          <div class="file-name">{{ getItemFileName(fileItem) }}</div>
          <div class="file-actions">
            <span class="action-link" @click.stop="handlePreview(fileItem)">预览</span>
            <span class="action-link" @click.stop="handleDownload(fileItem)">下载</span>
          </div>
        </div>
      </div>
    </div>

    <!-- Office文件预览对话框 -->
    <el-dialog
      v-model="officePreviewVisible"
      :title="getFileName(currentPreviewUrl)"
      width="90vw"
      maxHeight="90vh"
      :before-close="closeOfficePreview"
      destroy-on-close
      :z-index="99999"
      :modal="true"
      :close-on-click-modal="true"
      :close-on-press-escape="true"
      :lock-scroll="true"
      append-to-body
    >
      <div class="office-preview-container">
        <!-- 调试信息 -->
        <div v-if="showDebug && currentFileType" class="debug-info">
          文件类型: {{ currentFileType }} | 文件URL: {{ currentPreviewUrl }}
        </div>

        <!-- PDF预览 -->
        <div v-if="currentFileType === 'pdf'" class="pdf-container">
          <!-- 尝试使用vue-office -->
          <VueOfficePdf
            v-if="!pdfFallback"
            :src="currentPreviewUrl"
            class="office-viewer"
            @rendered="onPdfRendered"
            @error="onPdfError"
          />
          <!-- 备选方案：使用iframe -->
          <div v-else class="fallback-container">
            <iframe
              :src="currentPreviewUrl + '#toolbar=0'"
              class="pdf-iframe"
              @error="onIframeError"
            ></iframe>
            <div class="fallback-actions">
              <el-button type="primary" @click="openInNewWindow"> 在新窗口中打开PDF </el-button>
            </div>
          </div>
        </div>
        <!-- Word文档预览 -->
        <VueOfficeDocx
          v-else-if="currentFileType === 'docx'"
          :src="currentPreviewUrl"
          class="office-viewer"
        />
        <!-- Excel表格预览 -->
        <VueOfficeExcel
          v-else-if="currentFileType === 'xlsx'"
          :src="currentPreviewUrl"
          class="office-viewer"
        />
        <!-- PowerPoint预览 -->
        <VueOfficeDocx
          v-else-if="currentFileType === 'pptx'"
          :src="currentPreviewUrl"
          class="office-viewer"
        />
        <!-- 未识别的文件类型 -->
        <div v-else class="unsupported-file">
          <p>不支持的文件类型: {{ currentFileType }}</p>
          <el-button @click="openInNewWindow">在新窗口中打开</el-button>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import { Document } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import VueOfficeDocx from '@vue-office/docx'
import VueOfficeExcel from '@vue-office/excel'
import VueOfficePdf from '@vue-office/pdf'
import { createImageViewer } from '@/components/ImageViewer'

interface FileItem {
  id?: number
  url: string
  name?: string
  alt?: string
}

interface Props {
  fileList: (string | FileItem)[]
  singleSize?: number
  itemSize?: number
  maxDisplay?: number
  showDebug?: boolean
  inlineWrap?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  singleSize: 80,
  itemSize: 60,
  maxDisplay: 3,
  showDebug: false,
  inlineWrap: false
})

// Office文件预览相关
const officePreviewVisible = ref(false)
const currentPreviewUrl = ref('')
const currentFileType = ref('')
const pdfFallback = ref(false)

// 辅助函数：获取文件URL
const getFileUrl = (item: string | FileItem): string => {
  return typeof item === 'string' ? item : item.url
}

// 辅助函数：获取文件名
const getItemFileName = (item: string | FileItem): string => {
  if (typeof item === 'string') {
    return item.split('/').pop() || ''
  }
  return item.name || item.url.split('/').pop() || ''
}

// 计算属性：获取所有图片文件URL
const imageList = computed(() => {
  return props.fileList.map((item) => getFileUrl(item)).filter((url) => isImageFile(url))
})

// 文件类型判断函数
const isImageFile = (url: string): boolean => {
  if (!url) return false
  const imageExtensions = ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'webp']
  const fileExtension = url.split('.').pop()?.toLowerCase()
  return imageExtensions.includes(fileExtension || '')
}

const isOfficeFile = (url: string): boolean => {
  if (!url) return false
  const officeExtensions = ['pdf', 'docx', 'xlsx', 'pptx']
  const fileExtension = url.split('.').pop()?.toLowerCase()
  return officeExtensions.includes(fileExtension || '')
}

const getFileType = (url: string): string => {
  if (!url) return 'unknown'
  const extension = url.split('.').pop()?.toLowerCase() || ''

  if (isImageFile(url)) return 'image'
  if (extension === 'pdf') return 'pdf'
  if (extension === 'docx' || extension === 'doc') return 'word'
  if (extension === 'xlsx' || extension === 'xls') return 'excel'
  if (extension === 'pptx' || extension === 'ppt') return 'powerpoint'

  return 'file'
}

const getFileIcon = (url: string): string => {
  const fileType = getFileType(url)

  // 返回对应的图标路径，这里使用base64图标或者CDN图标
  const iconMap: Record<string, string> = {
    image:
      '',
    pdf: '',
    word: '',
    excel:
      '',
    powerpoint:
      '',
    file: ''
  }

  return iconMap[fileType] || iconMap.file
}

const getFileName = (url: string): string => {
  if (!url) return ''
  const fileName = url.split('/').pop() || ''
  return fileName.length > 10 ? fileName.substring(0, 10) + '...' : fileName
}

const getFullFileName = (url: string): string => {
  if (!url) return ''
  return url.split('/').pop() || ''
}

// 文件操作函数
const handleFileClick = (item: string | FileItem) => {
  // 点击文件项时的默认行为（可以是预览或下载）
  handlePreview(item)
}

const handlePreview = (item: string | FileItem) => {
  const url = getFileUrl(item)
  if (!url) return

  const fileType = getFileType(url)

  if (fileType === 'image') {
    // 图片预览 - 创建图片查看器
    openImageViewer(url)
  } else if (isOfficeFile(url)) {
    // Office文件预览
    openOfficePreview(url)
  } else {
    // 其他文件直接在新窗口打开
    openFile(url)
  }
}

const handleDownload = (item: string | FileItem) => {
  const url = getFileUrl(item)
  const fileName = getItemFileName(item)
  if (!url) return

  // 在新标签页打开下载链接
  const link = document.createElement('a')
  link.href = url
  link.download = fileName
  link.target = '_blank'
  link.rel = 'noopener noreferrer'
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

const openImageViewer = (url: string) => {
  // 获取所有图片文件的URL
  const imageUrls = props.fileList
    .map((item) => getFileUrl(item))
    .filter((fileUrl) => isImageFile(fileUrl))
  const currentIndex = imageUrls.indexOf(url)

  // 使用项目的 createImageViewer 函数
  createImageViewer({
    urlList: imageUrls,
    initialIndex: currentIndex,
    zIndex: 99999
  })
}

const openFile = (url: string) => {
  if (!url) return
  window.open(url, '_blank')
}

const openOfficePreview = (url: string) => {
  if (!url) return
  console.log('Opening office preview for:', url)

  // 强制阻止页面滚动和交互
  document.body.style.overflow = 'hidden'
  document.body.style.position = 'fixed'
  document.body.style.width = '100%'
  document.body.style.top = `-${window.scrollY}px`

  currentPreviewUrl.value = url
  const fileExtension = url.split('.').pop()?.toLowerCase()
  currentFileType.value = fileExtension || ''
  pdfFallback.value = false // 重置PDF备选方案状态
  console.log('File type:', currentFileType.value)
  officePreviewVisible.value = true

  // 延迟添加事件监听器防止穿透
  setTimeout(() => {
    document.addEventListener('touchmove', preventScroll, { passive: false })
    document.addEventListener('wheel', preventScroll, { passive: false })
    document.addEventListener('keydown', preventArrowKeys, { passive: false })
  }, 100)
}

const closeOfficePreview = () => {
  // 获取滚动位置
  const scrollY = document.body.style.top ? -parseInt(document.body.style.top, 10) : 0

  officePreviewVisible.value = false
  currentPreviewUrl.value = ''
  currentFileType.value = ''
  pdfFallback.value = false

  // 恢复页面状态
  document.body.style.overflow = ''
  document.body.style.position = ''
  document.body.style.width = ''
  document.body.style.top = ''

  // 恢复滚动位置
  window.scrollTo(0, scrollY)

  // 移除事件监听器
  document.removeEventListener('touchmove', preventScroll)
  document.removeEventListener('wheel', preventScroll)
  document.removeEventListener('keydown', preventArrowKeys)
}

// 防止滚动的辅助函数（允许预览区域内滚动）
const preventScroll = (e: Event) => {
  const target = e.target as HTMLElement
  const previewContainer = document.querySelector('.office-preview-container')
  const officeViewer = document.querySelector('.office-viewer')
  const pdfIframe = document.querySelector('.pdf-iframe')

  // 如果滚动事件发生在预览容器内，允许滚动
  if (
    previewContainer &&
    (previewContainer.contains(target) ||
      (officeViewer && officeViewer.contains(target)) ||
      (pdfIframe && pdfIframe.contains(target)))
  ) {
    return true
  }

  // 否则阻止滚动
  e.preventDefault()
  e.stopPropagation()
  return false
}

// 防止方向键滚动（允许预览区域内使用方向键）
const preventArrowKeys = (e: KeyboardEvent) => {
  const target = e.target as HTMLElement
  const previewContainer = document.querySelector('.office-preview-container')
  const officeViewer = document.querySelector('.office-viewer')
  const pdfIframe = document.querySelector('.pdf-iframe')

  // 如果焦点在预览容器内，允许方向键
  if (
    previewContainer &&
    (previewContainer.contains(target) ||
      (officeViewer && officeViewer.contains(target)) ||
      (pdfIframe && pdfIframe.contains(target)))
  ) {
    return true
  }

  // 否则阻止方向键滚动
  if (
    [
      'ArrowUp',
      'ArrowDown',
      'ArrowLeft',
      'ArrowRight',
      'Space',
      'PageUp',
      'PageDown',
      'Home',
      'End'
    ].includes(e.code)
  ) {
    e.preventDefault()
    e.stopPropagation()
  }
}

const openInNewWindow = () => {
  if (currentPreviewUrl.value) {
    window.open(currentPreviewUrl.value, '_blank')
  }
}

// PDF渲染回调
const onPdfRendered = () => {
  console.log('PDF渲染成功')
}

const onPdfError = (error: any) => {
  console.error('PDF渲染失败:', error)
  ElMessage.warning('PDF预览失败，正在尝试备选方案...')
  // 切换到iframe备选方案
  pdfFallback.value = true
}

const onIframeError = () => {
  console.error('Iframe PDF预览也失败了')
  ElMessage.error('PDF文件无法预览，请点击按钮在新窗口中打开')
}
</script>

<style scoped>
.file-list-container {
  width: 100%;
}

.file-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.file-list.inline-wrap {
  flex-flow: row wrap;
}

.file-item {
  display: flex;
  padding: 8px;
  cursor: pointer;
  background: #fff;
  border: 1px solid #e5e5e5;
  border-radius: 6px;
  transition: all 0.3s ease;
  align-items: center;
}

.file-list.inline-wrap .file-item {
  max-width: calc(25% - 6px);
  box-sizing: border-box;
  flex: 0 0 calc(25% - 6px);
}

.file-item:hover {
  background: #f8f9fa;
  border-color: #409eff;
  box-shadow: 0 2px 4px rgb(0 0 0 / 10%);
}

.file-icon {
  padding: 4px;
  margin-right: 12px;
  cursor: pointer;
  border-radius: 4px;
  transition: all 0.3s ease;
  flex-shrink: 0;
}

.file-icon:hover {
  background-color: #f0f9ff;
  transform: scale(1.05);
}

.file-type-icon {
  width: 32px;
  height: 32px;
  object-fit: contain;
}

.file-info {
  flex: 1;
  min-width: 0;
  text-align: left;
}

.file-name {
  margin-bottom: 4px;
  overflow: hidden;
  font-size: 14px;
  color: #333;
  text-align: left;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-actions {
  display: flex;
  gap: 12px;
}

.action-link {
  font-size: 12px;
  color: #409eff;
  text-decoration: none;
  cursor: pointer;
  transition: color 0.3s ease;
}

.action-link:hover {
  color: #66b1ff;
  text-decoration: underline;
}

.office-preview-container {
  position: relative;
  display: flex;
  width: 100%;
  height: 70vh;
  overflow: auto;
  flex-direction: column;
  scrollbar-width: thin;
  scrollbar-color: #c1c1c1 #f1f1f1;
}

.office-preview-container::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

.office-preview-container::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 4px;
}

.office-preview-container::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 4px;
  transition: background 0.3s ease;
}

.office-preview-container::-webkit-scrollbar-thumb:hover {
  background: #a1a1a1;
}

.office-preview-container::-webkit-scrollbar-corner {
  background: #f1f1f1;
}

/* 防止对话框穿透 */
:deep(.el-overlay) {
  position: fixed !important;
  top: 0 !important;
  left: 0 !important;
  z-index: 99999 !important;
  width: 100% !important;
  height: 100% !important;
  pointer-events: auto !important;
  background-color: rgb(0 0 0 / 50%) !important;
}

:deep(.el-dialog__wrapper) {
  position: fixed !important;
  top: 0 !important;
  left: 0 !important;
  z-index: 99999 !important;
  width: 100% !important;
  height: 100% !important;
  overflow: hidden !important;
  pointer-events: auto !important;
}

:deep(.el-dialog) {
  position: relative !important;
  z-index: 99999 !important;
  pointer-events: auto !important;
}

:deep(.el-dialog__header) {
  pointer-events: auto !important;
}

:deep(.el-dialog__body) {
  overflow: hidden !important;
  pointer-events: auto !important;
}

:deep(.el-dialog__footer) {
  pointer-events: auto !important;
}

.debug-info {
  padding: 8px;
  margin-bottom: 10px;
  font-size: 12px;
  color: #666;
  background-color: #f5f5f5;
  border-radius: 4px;
}

.pdf-container {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.office-viewer {
  flex: 1;
  width: 100%;
  min-height: 500px;
  overflow: auto;
  scrollbar-width: thin;
  scrollbar-color: #c1c1c1 #f1f1f1;
  transform: scale(0.8);
  transform-origin: center top;
}

.office-viewer::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

.office-viewer::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 4px;
}

.office-viewer::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 4px;
  transition: background 0.3s ease;
}

.office-viewer::-webkit-scrollbar-thumb:hover {
  background: #a1a1a1;
}

.office-viewer::-webkit-scrollbar-corner {
  background: #f1f1f1;
}

.fallback-container {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.pdf-iframe {
  width: 100%;
  overflow: auto;
  border: none;
  transform: scale(0.8);
  flex: 1;
  scrollbar-width: thin;
  scrollbar-color: #c1c1c1 #f1f1f1;
  transform-origin: center top;
}

.pdf-iframe::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

.pdf-iframe::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 4px;
}

.pdf-iframe::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 4px;
  transition: background 0.3s ease;
}

.pdf-iframe::-webkit-scrollbar-thumb:hover {
  background: #a1a1a1;
}

.pdf-iframe::-webkit-scrollbar-corner {
  background: #f1f1f1;
}

.fallback-actions {
  padding: 10px;
  margin-top: 10px;
  text-align: center;
}

.unsupported-file {
  padding: 50px;
  text-align: center;
}

.unsupported-file p {
  margin-bottom: 20px;
  color: #666;
}
</style>
